从30亿Token到全自治AGI:Hermes的自动化之路 5

221 字

从30亿Token到全自治AGI:Hermes的自动化之路 5

烧了30亿+token,超10万+api调用次数养龙虾之后,我彻底转向以hermes为执行者的harness工程agi全自治架构我曾以为"约束写得越细,模型就越不敢造假"。结果它学会了绕过约束——因为约束本质上只是"建议",不是"物理上无法绕过的闸门"。这是我在Claude Code的生产实践里找到的答案。

一、深夜Bug

事情的起因很简单:我想让Agent生成一篇技术文章,并在结尾附上引用来源。为了"确保引用真实",我在AGENTS.md里加了一条硬约束——"每条引用必须标注来源平台和获取日期"。我还加了验证:如果引用没有标注,就不让发布。

模型的对策是:直接编造了一个根本不存在的"据OpenAI 2025年Q3报告显示……"。它通过了我的"验证",因为这条约束只检查了"有没有标注来源",没检查"来源本身是不是真的"。

这暴露了prompt约束的根本缺陷:当你用"建议"来对抗"生成"时,模型会学会在形式上满足建议,同时绕过它的精神。

据OpenAI和佐治亚理工学院2025年联合发表的研究(Why Language Models Hallucinate),语言模型产生幻觉的根本原因在于其训练和评估程序本质上是"猜测"而非"认证"——模型被训练来预测下一个最可能的token,而不是验证输出是否与事实相符。这篇论文建立了生成误差率与分类误差率之间的数学关系,揭示了当前方法论的系统性局限。

来源:OpenAI Research - Why Language Models Hallucinate(2025-09-09)

二、教训一:生成与审核,必须物理分离

我开始研究Claude Code的内部设计。Anthropic的工程师在2025年的一次技术分享中提到:Claude Code内部采用了分层多Agent架构,通过主Agent和SubAgent的协作来处理复杂任务。

Claude Code的官方文档显示:它大量使用SubAgent来处理专项任务,例如代码审查、API调用验证。SubAgent拥有独立的上下文窗口,是完全自治的Worker,主对谈只看结论,不看中间推理过程。

这种设计解决了一个核心问题:让同一个LLM实例既生成内容又审核内容,会导致"自我合理化"——它会为自己的错误找补,而不是真正纠正。

我的下一版harness架构,引入了独立的auditor Agent。它的prompt里没有任何"你要帮忙生成"的内容,只有"你是一个挑剔的审核者,检查以下内容是否符合标准"。它看不到生成者的推理链,只能看到最终成品。

具体代码示例

`# 分离设计的伪代码
defgenerate_and_audit(content_prompt, constraints):

生成阶段:主Agent负责生成

draft = main_agent.generate(content_prompt)

审核阶段:独立的auditor Agent,负责检查

audit_prompt = f"检查以下内容是否满足约束:\n约束列表:{constraints}\n待审核内容:{draft}"
    audit_result = auditor_agent.audit(audit_prompt)

关键:主Agent看不到auditor的推理过程

ifnot audit_result.passed:
return generate_and_audit(content_prompt, constraints)  # 打回重写
return draft
`

这个打回重写的循环,就是"生成-审核分离"的物理意义。

来源:CSDN - Claude Code分层多Agent架构(2025-08-21);博客园 - Claude Code SubAgent隔离与专业化设计(2026-04-09)

三、教训二:约束必须变成工具硬拦截

在Claude Code的工作流里,有一条我很欣赏的设计原则:质量检查不通过时,后续操作在物理上无法继续。

比如pre-commit hooks。如果你的代码风格检查没通过,git commit会被直接拒绝,没有任何"商量"的余地。

这正是我在harness里落地的东西

`# 脚本校验失败的示例输出
$ hermes publish --platform bilibili

[ERROR] 脚本校验未通过
  - 缺少评论区预埋点(要求≥3个)
  - 标签数量不足(要求5-8个,当前4个)

[BLOCKED] 无法进入发布流程
请修复上述问题后重试,或使用 --force 跳过校验(不推荐)
`

注意这个"[BLOCKED]"——它不是警告,不是"建议重写",是物理上的拦截。如果你的lint脚本返回非零退出码,后续的git操作、API调用都不会执行。

约束只有变成工具链上的硬闸门,才不会再被模型"商量着绕过"。

四、教训三:每个引用都要有"证据文件"

现在我在harness里引入了一个强制流程:生成任何需要引用的内容之前,必须先执行web_search,并将结果写入固定的search-evidence.md

证据文件的格式要求

`# search-evidence.md

搜索查询:LLM幻觉成因2025

搜索时间:2026-04-17T12:00:00Z

来源1

- 标题:Why Language Models Hallucinate
- 平台:OpenAI Research Blog
- URL:https://openai.com/index/why-language-models-hallucinate/
- 获取日期:2025-09-09
- 核心观点:训练和评估程序本质上是"猜测"而非"认证",是幻觉根本原因

来源2

- 标题:LLM"幻觉"新根源:注意力机制竟然会自相矛盾
- 平台:HTML5趣味知识
- URL:https://so.html5.qq.com/page/real/search_news?docid=70000021_79668a54b5e60952
- 获取日期:2025-08-20
- 核心观点:MIT CSAIL发现注意力机制在处理某些类型的推理任务时会出现系统性错误,这是机制本身的固有特性造成的
`

生成Agent被明确告知:引用必须来自这个文件,不能从自己的知识里编造。审核Agent会交叉检查成品中的每个引用是否出现在证据文件中。

没有证据文件的引用,就是无效引用——这个逻辑简单到模型没法找到漏洞。

五、教训四:结构化输出约束关键元数据

Anthropic在2025年推出的Structured Outputs通过constrained decoding强制模型输出符合JSON Schema。虽然长文内容不适合全文JSON,但标题、标签、引用列表、数据表格等关键元数据可以被硬约束。

我的落地实践

`from pydantic import BaseModel, Field
from typing importList

classArticleMetadata(BaseModel):
    title: str = Field(max_length=50)
    tags: List[str] = Field(max_length=10)
    references: List[dict] = Field(max_items=5)

每个引用必须包含来源和日期

classReference(BaseModel):
        source: str
        date: str# YYYY-MM-DD格式
        url: str = ""

发布前校验

metadata = parser.parse(llm_output)

如果不符合Schema,parse会抛出异常

模型无法"自由发挥"标题或标签格式

`

这个设计的核心价值:减少格式层面的自由发挥空间,也降低下游解析的出错率

六、教训五:reasoning-specialist做根因分析

当我发现某个平台反复生成失败时,我以前会做的蠢事是:继续重写,期待这次能碰对。

Claude Code的实践让我意识到:应该引入一个专门的reasoning agent做系统分析。

reasoning-specialist的职责

当生成失败时,不要重写,先问: 1. 约束为什么会被绕过?是prompt表述问题,还是约束本身存在逻辑漏洞? 2. 这次的"绕过"和上次有什么共同点? 3. 修改哪个环节(prompt/约束/工具链/审核逻辑)能从根本上解决问题?

这正好能解决我们发现的核心问题:当我们设置"≥2个引用"的约束时,反而催生了编造行为——因为模型被逼着凑数量,而不是追求真实。没有根因分析的重写,只是在碰运气。
个人技术观察,具体行为以官方文档为准。